package com.xinxi11.project.qx.filter;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.centfor.core.cache.ICacheUser;
import com.centfor.core.cache.ILoginUserInfo;
import com.centfor.core.module.ConfigPropUtil;
import com.centfor.core.spring.SpringContextHolder;
import com.centfor.core.utils.HttpUtils;

/**
 * URL访问权限过滤器
 * 
 * @author 李国江
 * @date 2011-8-24
 */
public class ForbidenFilter implements Filter {

	public static final String loginAction = ConfigPropUtil
			.getProperty("cas_login_url");
	public static final String user_access = "用户 {0} 访问资源 {1} ";
	public static final String forbiden_access = "用户 {0} 访问被禁止的资源 {1} ";
	public static final String exclude_access = "用户 {0} 访问被排除的资源 {1}";
	public static final String notExist_access = "用户 {0} 访问不存在的资源 {1}";

	/** 需要排除的URL的正则验证规则.默认排除包含ajax,login,logout字符的URL */
	private static final String excludeRegex = ConfigPropUtil
			.getProperty("url_forbiden_exclude_regex",
					"/([a-zA-Z_0-9./]*_ajax|login|logout|main)[a-zA-Z_0-9./]*(.action|.jsp|.do)$");

	protected Logger log = LoggerFactory.getLogger(getClass());
	private static ICacheUser cacheUser;

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest servletRequest,
			ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		String uri = request.getRequestURI();
		String url = HttpUtils.getURL(request);
		Pattern pattern = Pattern.compile(excludeRegex);
		Matcher matcher = pattern.matcher(uri);
		boolean isExclude = matcher.matches();
		String userCode = getLoginUserCode(request);
		if (isExclude) {// 执行过滤
			log.info(MessageFormat.format(exclude_access, userCode, url));
		} else {
			if (!isAccess(userCode, uri)) {
				// 用户越权访问URL,或者URL不存在,跳转到登陆页面
				HttpServletResponse httpServletResponse = (HttpServletResponse) response;
				log.error(MessageFormat.format(forbiden_access, userCode, url));
				httpServletResponse.sendRedirect(loginAction);
				return;
			}
			// 用户正常访问
			log.debug(MessageFormat.format(user_access, userCode, url));
		}
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	String getLoginUserCode(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session == null) {
			return null;
		}
		String userCode = (String) session
				.getAttribute(SpringContextHolder.USER_LOGIN_ID);
		if (userCode == null || "".equals(userCode.trim())) {
			return null;
		}
		return userCode.trim();
	}

	public static Boolean isAccess(String userCode, String uri) {
		if (cacheUser == null) {
			cacheUser = SpringContextHolder.getBean("cacheUser");
		}
		ILoginUserInfo user = cacheUser.findCacheUserInfo(userCode);
		if (user.getModels() != null) {
			return user.getModels().contains(uri);
		}
		return true;
	}

}
